//
//  OwlSourceListViewController.m
//  Owl
//
//  Created by Tianzhou on 09-2-10.
//  Copyright 2009 Tianzhou Software Inc.. All rights reserved.
//

#import "OwlSourceListViewController.h"
#import "OwlDocument.h"
#import "BaseNode.h"
#import "ChildNode.h"
#import "ImageAndTextCell.h"
#import "OwlSupport.h"
#import "OwlWCFacility.h"

NSString *const kProjectGroupName = @"Project";
NSString *const kProjectLogGroupName = @"Project Log";
NSString *const kColumnName = @"SourceListColumn";

@interface OwlSourceListViewController (Private_Method)

-(void)performAddChild:(ChildNode *)newChildNode;
-(NSIndexPath *)performAddFolder:(ChildNode *)newFolderNode;

- (void)addProjectRootNode;
- (void)addProjectLogRootNode;

- (BOOL)isSpecialGroup:(BaseNode *)groupNode;

@end

@implementation OwlSourceListViewController (Private_Method)

- (BOOL)isSpecialGroup:(BaseNode *)groupNode
{ 
	return ([groupNode nodeIcon] == nil 
			|| [[groupNode nodeTitle] isEqualToString:kProjectGroupName] 
			|| [[groupNode nodeTitle] isEqualToString:kProjectLogGroupName]);
}


- (void)performAddChild:(ChildNode *)theNode
{
	NSIndexPath *indexPath;
	indexPath = [NSIndexPath indexPathWithIndex:[[[self representedObject] contents] count]];
	
	ChildNode *node = [[ChildNode alloc] initLeaf];
	[node setNodeTitle:[theNode nodeTitle]];
	
	[sourceListController_ insertObject:node 
			  atArrangedObjectIndexPath:indexPath];
	//[node release];
}

-(NSIndexPath *)performAddFolder:(ChildNode *)newFolderNode
{
	NSIndexPath *indexPath;
	indexPath = [NSIndexPath indexPathWithIndex:[[[self representedObject] contents] count]];
	
	//ChildNode *node = [[ChildNode alloc] init];
	//[node setNodeTitle:[newFolderNode nodeTitle]];
	
	[sourceListController_ insertObject:newFolderNode 
			  atArrangedObjectIndexPath:indexPath];
	//[node release];
	return indexPath;
}

- (void)addProjectRootNode
{	
	ChildNode *theNode = [[ChildNode alloc] init];
	[theNode setNodeTitle:kProjectGroupName];
	[theNode setNodeIcon:nil];
	projectRootIndexPath_ = [self performAddFolder:theNode];
	projectRootNode_ = [[[self representedObject] contents] lastObject]; 
	[theNode release];

#if USE_SHELL
	NSString *directoryName = [NSString stringWithString:@"/Users/Tianzhou/Desktop/NSOperationSample"];
	NSString *projectName = [directoryName lastPathComponent];
	ChildNode *theProjectNode = [[ChildNode alloc] init];
	
	NSArray *wcDataArray;
	[OwlWCFacility gatherWCData:&wcDataArray
					  UnderPath:directoryName];
	[theProjectNode setNodeTitle:projectName];
	[theProjectNode setURLString:directoryName];
	[theProjectNode setNodeIcon:[[NSWorkspace sharedWorkspace] iconForFile:[theProjectNode urlString]]];
	[theProjectNode setLeaf:![wcDataArray count]];
	
	[sourceListController_ setSelectionIndexPath:projectRootIndexPath_];
	NSIndexPath *indexPath = [projectRootIndexPath_ indexPathByAddingIndex:[[[[sourceListController_ selectedObjects] objectAtIndex:0] children] count]];
	[sourceListController_ setSelectionIndexPath:nil];
	[sourceListController_ insertObject:theProjectNode atArrangedObjectIndexPath:indexPath];
	
	NSMutableArray *theFileNodes = [NSMutableArray arrayWithCapacity:[wcDataArray count]];
	NSMutableArray *theFileNodesIndexPaths = [NSMutableArray arrayWithCapacity:[wcDataArray count]];
	
	int totalLines = 0;
	for (WCDataHolder *tempHolder in wcDataArray )
	{
		// the last element is the total lines;
		if (tempHolder == [wcDataArray objectAtIndex:[wcDataArray count] - 1])
		{
			totalLines = [tempHolder lineCount];
		}
		else
		{
			ChildNode *theFileNode = [[ChildNode alloc] init];
			[theFileNode setNodeTitle:[[tempHolder fileURL] lastPathComponent]];
			[theFileNode setURLString:[tempHolder fileURL]];
			[theFileNode setNodeIcon:[[NSWorkspace sharedWorkspace] iconForFile:[theFileNode urlString]]];
			[theFileNode setLineCount:[tempHolder lineCount]];
			[theFileNode setLeaf:YES];
		
			[theFileNodesIndexPaths addObject:[indexPath indexPathByAddingIndex:[theFileNodesIndexPaths count]]];
			[theFileNodes addObject:theFileNode];
			[theFileNode release];
		}
	}
#else
	NSString *directoryName = [NSString stringWithString:@"/Users/Tianzhou/Desktop/XSController_DocumentExtension"];
	NSArray *allFiles = [OwlSupport interestedFilesUnderPath:directoryName];
	NSString *projectName = [directoryName lastPathComponent];
	ChildNode *theProjectNode = [[ChildNode alloc] init];
	
	[theProjectNode setNodeTitle:projectName];
	[theProjectNode setURLString:directoryName];
	[theProjectNode setNodeIcon:[[NSWorkspace sharedWorkspace] iconForFile:[theProjectNode urlString]]];
	[theProjectNode setLeaf:![allFiles count]];
	//[theNode setNodeIcon:folderImage_];
	//[self performAddFolder:theProjectNode];
	[sourceListController_ setSelectionIndexPath:projectRootIndexPath_];
	NSIndexPath *indexPath = [projectRootIndexPath_ indexPathByAddingIndex:[[[[sourceListController_ selectedObjects] objectAtIndex:0] children] count]];
	[sourceListController_ setSelectionIndexPath:nil];
	[sourceListController_ insertObject:theProjectNode atArrangedObjectIndexPath:indexPath];
	
	NSMutableArray *theFileNodes = [NSMutableArray arrayWithCapacity:[allFiles count]];
	NSMutableArray *theFileNodesIndexPaths = [NSMutableArray arrayWithCapacity:[allFiles count]];
	
	directoryName = [directoryName stringByAppendingString:@"/"];
	
	int totalLines = 0;
	for (NSString *fileName in allFiles)
	{
		ChildNode *theFileNode = [[ChildNode alloc] init];
		int lineCount;
		[theFileNode setNodeTitle:fileName];
		[theFileNode setURLString:[directoryName stringByAppendingString:fileName]];
		[theFileNode setNodeIcon:[[NSWorkspace sharedWorkspace] iconForFile:[theFileNode urlString]]];
		lineCount = [OwlWCFacility calculateLineCountForFile:fileName atFolder:directoryName];
		[theFileNode setLineCount:lineCount];
		[theFileNode setLeaf:YES];
	
		[theFileNodesIndexPaths addObject:[indexPath indexPathByAddingIndex:[theFileNodesIndexPaths count]]];
		[theFileNodes addObject:theFileNode];
		[theFileNode release];
		totalLines +=lineCount;
	}
#endif
	[theProjectNode setChildren:theFileNodes];
	[theProjectNode setLineCount:totalLines];
	//[sourceListController_ insertObjects:theFileNodes atArrangedObjectIndexPaths:theFileNodesIndexPaths];
	
	[theProjectNode release];
}

- (void)addProjectLogRootNode
{
	ChildNode *theNode = [[ChildNode alloc] init];
	[theNode setNodeTitle:kProjectLogGroupName];
	[theNode setNodeIcon:nil];
	[self performAddFolder:theNode];
	[theNode release];
}

@end

@implementation OwlSourceListViewController

@synthesize sourceListController = sourceListController_;
@synthesize filterString = filterString_;

//- (id)sourceListObserver
//{
//	return observer_;
//}
//
//- (void)setSourceListObserver:(id)newObserver
//{
//	if (newObserver != observer_)
//	{
//		if (observer_)
//		{
//			[sourceListController_ removeObserver:observer_ forKeyPath:@"selectedObjects"];
//		}
//		[sourceListController_ addObserver:newObserver
//								forKeyPath:@"selectedObjects"
//								   options:NSKeyValueObservingOptionNew
//								   context:nil];
//		observer_ = newObserver;
//	}
//}

- (IBAction)importProject:(id)sender
{
	NSLog(@"import Project:%@",[[[self view] window] description]);
	int result;
	NSOpenPanel *theOpenPanel = [NSOpenPanel openPanel];
	
	[theOpenPanel setCanChooseFiles:NO];
	[theOpenPanel setCanChooseDirectories:YES];
	[theOpenPanel setAllowsMultipleSelection:NO];
	result = [theOpenPanel runModalForDirectory:NSHomeDirectory() 
										   file:nil];
	if (result == NSOKButton)
	{
		NSString *directoryName = [[theOpenPanel filenames] objectAtIndex:0];
		NSArray *allFiles = [OwlSupport interestedFilesUnderPath:directoryName];
		NSString *projectName = [directoryName lastPathComponent];
		ChildNode *theProjectNode = [[ChildNode alloc] init];
		
		[theProjectNode setNodeTitle:projectName];
		[theProjectNode setLeaf:![allFiles count]];
		//[theNode setNodeIcon:folderImage_];
		//[self performAddFolder:theProjectNode];
		[sourceListController_ setSelectionIndexPath:projectRootIndexPath_];
		NSIndexPath *indexPath = [projectRootIndexPath_ indexPathByAddingIndex:[[[[sourceListController_ selectedObjects] objectAtIndex:0] children] count]];
		[sourceListController_ insertObject:theProjectNode atArrangedObjectIndexPath:indexPath];
		
		NSMutableArray *theFileNodes = [NSMutableArray arrayWithCapacity:[allFiles count]];
		NSMutableArray *theFileNodesIndexPaths = [NSMutableArray arrayWithCapacity:[allFiles count]];
		
		for (NSString *fileName in allFiles)
		{
			ChildNode *theFileNode = [[ChildNode alloc] init];
			[theFileNode setNodeTitle:fileName];
			[theFileNode setLeaf:YES];
			[theFileNodesIndexPaths addObject:[indexPath indexPathByAddingIndex:[theFileNodesIndexPaths count]]];
			[theFileNodes addObject:theFileNode];
			[theFileNode release];
		}
		
		[theProjectNode setChildren:theFileNodes];
		[sourceListController_ insertObjects:theFileNodes atArrangedObjectIndexPaths:theFileNodesIndexPaths];
		
		[theProjectNode release];
		
	}
	
}

- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle windowController:(XSWindowController *)windowController;
{
	if (![super initWithNibName:name bundle:bundle windowController:windowController])
	{
		return nil;
	}
	[self setRepresentedObject:[windowController document]];
	folderImage_ = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] retain];
	//contents_ = [[NSMutableArray alloc] init];
	return self;
}

- (void)dealloc
{
//	if (observer_)
//	{
//		if (observer_)
//		{
//			[sourceListController_ removeObserver:observer_ forKeyPath:@"selectedObjects"];
//		}
//	}
	[folderImage_ release];
	//[contents_ release];
	[super dealloc];
}

- (void)awakeFromNib
{
	NSLog(@"sourcelist view controller awake:");
	//[sourceListView_ setFrame:NSMakeRect([sourceListView_ frame].origin.x, [sourceListView_ frame].origin.y-20, [sourceListView_ frame].size.width, [sourceListView_ frame].size.height-20)];
	[sourceListView_ setFrame:NSMakeRect(1,1,1,1)];
	NSTableColumn *tableColumn = [sourceListView_ tableColumnWithIdentifier:kColumnName];
	ImageAndTextCell *imageAndTextCell = [[[ImageAndTextCell alloc] init] autorelease];
	[imageAndTextCell setEditable:YES];
	[tableColumn setDataCell:imageAndTextCell];
	[self addProjectRootNode];
	[self addProjectLogRootNode];
	
}

// -------------------------------------------------------------------------------
//	setContents:newContents
// -------------------------------------------------------------------------------
//- (void)setContents:(NSArray *)newContents
//{
//	if (contents_ != newContents)
//	{
//		[contents_ release];
//		contents_ = [[NSMutableArray alloc] initWithArray:newContents];
//	}
//}
//
// -------------------------------------------------------------------------------
//	contents:
// -------------------------------------------------------------------------------
//- (NSMutableArray *)contents
//{
//	return contents_;
//}

// -------------------------------------------------------------------------------
//	isSpecialGroup:
// -------------------------------------------------------------------------------


#pragma mark outline delegate
- (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
	ChildNode *node = [item representedObject];
	[(ImageAndTextCell*)cell setImage:[node nodeIcon]];
//	if ([[tableColumn identifier] isEqualToString:kColumnName])
//	{
//		if([cell isKindOfClass:[ImageAndTextCell class]])
//		{
//			item = [item representedObject];
//			
//			//ChildNode *theNode = (ChildNode*)item;
//			if (item)
//			{
//				if ([item isLeaf])
//				{
//					[item setNodeIcon:nil];
//				}
//				else
//				{
//					[item setNodeIcon:folderImage_];
//				}
//			}
//			// set the cell's image
//			[(ImageAndTextCell*)cell setImage:[item nodeIcon]];
//		}
//	}
}

- (void)outlineViewSelectionDidChange:(NSNotification *)notification
{
	if ([notification object] == sourceListView_)
	{
		NSInteger selectedRow = [sourceListView_ selectedRow];
		if (selectedRow >= 0)
		{
			ChildNode *selectedNode = [[sourceListView_ itemAtRow:selectedRow] representedObject];
			NSArray *tA = [selectedNode children];
			if ([tA count]>0)
			{
				ChildNode *theNode = [tA objectAtIndex:0];

				//NSLog(@"%d",[tA count]);
			}
			[[self representedObject] setSelectedNode:selectedNode];
		}
	}
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
	// don't allow special group nodes (Devices and Places) to be selected
	BaseNode* node = [item representedObject];
	return (![self isSpecialGroup:node]);
}

@end

@implementation OwlNumberTransformer

+ (Class)transformedValueClass 
{ 
	return [NSNumber class]; 
}

+ (BOOL)allowsReverseTransformation 
{ 
	return NO; 
}

- (id)transformedValue:(id)value 
{
    return (value == nil || [value stringValue]) ? 0 : [value stringValue];
}

@end

@implementation OwlStringTransformer

+ (Class)transformedValueClass 
{ 
	return [NSString class]; 
}

+ (BOOL)allowsReverseTransformation 
{ 
	return NO; 
}

- (id)transformedValue:(id)value 
{
    return (value == nil) ? nil : value;
}

@end

